﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using System.Windows.Media;
using 工业设备监控系统.BLL;
using 工业设备监控系统.configure;
using 工业设备监控系统.Interface;
using 工业设备监控系统.Models;

namespace 工业设备监控系统
{
    public partial class MainFrm : Form
    {
        private IModbusConnection connection;
        private GetADRValuesBLL getADRValuesBLL = new GetADRValuesBLL();

        private List<Device> devices = new List<Device>();
        private List<Register> registers = new List<Register>();
        private List<Alarm> alarms = new List<Alarm>();
        private List<Register> registerCurrent = new List<Register>();

        private Register currentRegister = new Register();

        private Device currentdevice = new Device();

        public event Func<int, int> GetRegisterValue;

        private ModbusFrm modbus = new ModbusFrm();

        private Dictionary<int, List<int>> addressDataDict = new Dictionary<int, List<int>>();

        private System.Timers.Timer _threadTimer;

        public MainFrm()
        {
            InitializeComponent();
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            // 只保留横线
            dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal;
            dataGridView1.AutoGenerateColumns = false;
            dataGridView1.CellFormatting += DataGridView1_CellFormatting;
            _threadTimer = new System.Timers.Timer();
            _threadTimer.Interval = 3500;
            _threadTimer.Elapsed += _threadTimer_Elapsed;
            _threadTimer.AutoReset = true;
        }

        private void _threadTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            this.Invoke(new Action(() =>
            {
                int address = currentRegister.Address;
                if (address == 0)
                {
                    _threadTimer.Stop();
                    return;
                }
                int currentValue = 0;
                if (currentdevice != null && currentdevice.CommunicationType == "RTU")
                {
                    currentValue = modbus.MainFrm_GetRegisterValue(address);
                }
                else if (currentdevice != null && currentdevice.CommunicationType == "TCP")
                {
                    if (connection != null && connection.Connect())
                    {
                        currentValue = connection.ReadHoldingRegisters(address, 1)[0];
                    }
                    else
                    {
                        Addlog(1, "打开连接失败!");
                        _threadTimer.Stop();
                        return;
                    }
                }
                else
                {
                    _threadTimer.Stop();
                    Addlog(1, "不支持的通信类型");
                    return;
                }
                if (currentValue < 0 && currentRegister == null)
                {
                    _threadTimer.Stop();
                    Addlog(1, "你未连接Modbus!无法获取数据");
                    return;
                }
                // 如果字典中不存在该地址的列表，则创建新列表
                if (!addressDataDict.ContainsKey(address))
                {
                    addressDataDict[address] = new List<int>();
                }
                currentRegister.Value = currentValue;

                IsColor(currentRegister);

                registerCurrent.Add(currentRegister);
                dataGridView1.DataSource = registerCurrent;
                dataGridView1.Refresh();

                // 获取当前寄存器值并添加到对应地址的列表中
                addressDataDict[address].Add(currentValue);

                // 配置图表
                chart1.Series.Clear();
                Series series = new Series(currentRegister.Name);
                series.ChartType = SeriesChartType.Line;
                series.XValueType = ChartValueType.DateTime;
                series.Color = System.Drawing.Color.Red;
                chart1.Series.Add(series);

                // 配置坐标轴
                Axis xAxis = chart1.ChartAreas[0].AxisX;
                xAxis.LabelStyle.Format = "HH:mm";
                xAxis.Interval = 0;

                xAxis.IsMarginVisible = true;
                Axis yAxis = chart1.ChartAreas[0].AxisY;
                yAxis.Minimum = 0;

                // 获取当前地址对应的数据列表
                List<int> currentAddressData = addressDataDict[address];

                // 生成时间点（根据数据数量动态生成）
                DateTime baseTime = DateTime.Now.AddMinutes(-currentAddressData.Count);
                for (int i = 0; i < currentAddressData.Count; i++)
                {
                    DateTime timePoint = baseTime.AddMinutes(i);
                    series[timePoint.ToString()] = "0.8";
                    series.Points.AddXY(timePoint, currentAddressData[i]);
                }
                if (currentAddressData.Count == 11)
                {
                    currentAddressData.Clear();
                }

                chart1.Invalidate();
            }));
        }

        private void DataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            // 检查是否是 "StatusLed" 这一列
            if (dataGridView1.Columns[e.ColumnIndex].Name == "StatusLed")
            {
                // 获取当前行绑定的数据对象（即 Register）
                var register = dataGridView1.Rows[e.RowIndex]?.DataBoundItem as Register;

                if (register != null)
                {
                    // 根据 StatusColor 生成对应的灯图像
                    e.Value = LedIndicator.Create(register.StatusColor, 20); // 20px 大小
                    e.FormattingApplied = true; // 表示已处理
                }
            }
        }

        private void MainFrm_Load(object sender, EventArgs e)
        {
            this.toolStripStatusLabel7.Text = DateTime.Now.ToString();

            devices = getADRValuesBLL.GetAllDeviceData(); ;
            registers = getADRValuesBLL.GetAllRegisterData();
            alarms = getADRValuesBLL.GetAllAlarmData();
            foreach (var device in devices)
            {
                TreeNode parentNode = new TreeNode(device.Name);

                treeView1.Nodes.Add(parentNode);
                foreach (var register in registers)
                {
                    if (device.Id == register.DeviceId)
                    {
                        parentNode.Nodes.Add(register.Name);
                    }
                }
            }
            deviceCount.Text = devices.Count.ToString() + "      ";
            var a = devices.FindAll(v => v.Status == "运行").ToArray();
            currentOnline.Text = a.Length.ToString() + "     ";
        }

        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            TreeNode clickedNode = e.Node;
            if (devices == null || registers == null) return;
            var device = devices.FirstOrDefault(v => v.Name == clickedNode.Text);
            currentdevice = device;
            if (device == null) return;
            var register = registers.FindAll(v => v.DeviceId == device.Id);
            registerCurrent = register;
            foreach (var re in register)
            {
                IsColor(re);
            }

            //  先清空已有的 Image 列，避免重复添加
            var existingLedColumn = dataGridView1.Columns["StatusLed"];
            if (existingLedColumn != null)
            {
                dataGridView1.Columns.Remove(existingLedColumn);
            }
            dataGridView1.DataSource = null;
            dataGridView1.DataSource = register;

            var ledColumn = new DataGridViewImageColumn
            {
                Name = "StatusLed",
                Width = 30,
            };
            dataGridView1.Columns.Add(ledColumn);
        }

        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            DataGridViewRow currentRow = dataGridView1.Rows[e.RowIndex];
            currentRegister = currentRow.DataBoundItem as Register;
        }

        private void treeView1_Click(object sender, EventArgs e)
        {
        }

        //系统当前时间
        private static string CurrentTime
        {
            get { return DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"); }
        }

        public void Addlog(int type, string info)
        {
            ListViewItem lst = new ListViewItem(CurrentTime, type);
            lst.SubItems.Add(info);
            lstv_RWmessage.Items.Add(lst);
        }

        private void tsb_Star_Click(object sender, EventArgs e)
        {
            if (currentRegister.Address == 0) Addlog(1, "请选择需要查看的数据");
            _threadTimer.Start();
        }

        private void tsb_Stop_Click(object sender, EventArgs e)
        {
            _threadTimer.Stop();
            Addlog(0, "已停止");
        }

        /// <summary>
        /// 导出excel
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsb_Save_Click(object sender, EventArgs e)
        {
            try
            {
                // 1. 创建保存文件对话框
                using (SaveFileDialog saveDialog = new SaveFileDialog())
                {
                    saveDialog.Title = "保存 CSV 文件";
                    saveDialog.Filter = "CSV 文件 (*.csv)|*.csv|所有文件 (*.*)|*.*";
                    saveDialog.FilterIndex = 1;
                    saveDialog.RestoreDirectory = true;
                    saveDialog.FileName = $"监控数据_{DateTime.Now:yyyyMMdd_HHMM}.csv"; // 默认文件名

                    // 2. 显示对话框并检查用户是否点击了“保存”
                    if (saveDialog.ShowDialog(this) == DialogResult.OK)
                    {
                        string filePath = saveDialog.FileName;

                        // 3. 构建 CSV 内容
                        StringBuilder csv = new StringBuilder();

                        // 写入标题行（假设 registers 是包含 Address, Name, Value 等的类）
                        csv.AppendLine("地址,名称,当前值,单位");

                        // 遍历数据并写入每一行
                        foreach (var reg in registers)
                        {
                            // 示例：假设 reg 有这些属性
                            // 如果你的类字段不同，请替换为实际属性名
                            string line = $"{reg.Address},{reg.Name},{reg.Value},{reg.Unit}";
                            csv.AppendLine(line);
                        }

                        // 4. 写入文件（UTF-8 编码，支持中文）
                        File.WriteAllText(filePath, csv.ToString(), Encoding.UTF8);

                        // 5. 提示用户成功
                        MessageBox.Show($"数据已成功导出到：\n{filePath}", "导出成功",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"导出失败：{ex.Message}", "错误",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void modbusTCP配置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            modbus.ShowDialog();
            connection = modbus.GetModbusTcp();
            //  modbusTcp.ReadHoldingRegisters
        }

        private void tsb_config_Click(object sender, EventArgs e)
        {
            if (currentdevice == null)
            {
                Addlog(1, "请选中机器组!");
                return;
            }

            UpdateData updateData = new UpdateData(currentdevice.Id, currentdevice.Name, currentdevice.Description, currentdevice.CommunicationType, currentdevice.IpAddress, currentdevice.Port, currentdevice.PortName, currentdevice.BaudRate, currentdevice.Status, currentdevice.IsEnabled);

            updateData.ShowDialog();
        }

        private void tsb_Configmodus_Click(object sender, EventArgs e)
        {
            modbus.ShowDialog();
            connection = modbus.GetModbusTcp();
        }

        private void IsColor(Register currentRegister)
        {
            if (currentRegister.DataType == "Bool")
            {
                if (currentRegister.Value == 0)
                {
                    currentRegister.StatusColor = System.Drawing.Color.Red;
                }
                else
                {
                    currentRegister.StatusColor = System.Drawing.Color.Green;
                }
                return;
            }
            if (currentRegister.Value > currentRegister.MinValue && currentRegister.Value < currentRegister.MaxValue)
            {
                currentRegister.StatusColor = System.Drawing.Color.Green;
            }
            else if (currentRegister.Value > currentRegister.MaxValue - 5 || currentRegister.Value < currentRegister.MinValue + 5)
            {
                currentRegister.StatusColor = System.Drawing.Color.Yellow;
                Addlog(1, currentRegister.Name + "接近阈值，请注意！");
            }
            else if (currentRegister.Value > currentRegister.MaxValue)
            {
                Addlog(2, currentRegister.Name + "过高");
                currentRegister.StatusColor = System.Drawing.Color.Red;
            }
            else
            {
                currentRegister.StatusColor = System.Drawing.Color.Red;
                Addlog(2, currentRegister.Name + "超过或低于阈值，不在安全范围内!");
            }
        }

        private void btn_Clear_Click(object sender, EventArgs e)
        {
            this.lstv_RWmessage.Items.Clear();
        }
    }
}